package cn.bonoon.kernel.web.controllers;

import java.util.ArrayList;
import java.util.List;

import cn.bonoon.kernel.expression.IExpressionParameter;
import cn.bonoon.kernel.expression.QueryParameter;
import cn.bonoon.kernel.expression.QueryParameterType;
import cn.bonoon.kernel.support.OperandSupport;
import cn.bonoon.kernel.util.StringHelper;
import cn.bonoon.kernel.web.ButtonEventType;
import cn.bonoon.kernel.web.ButtonRefreshType;

/**
 * <pre>
 * 生成一个操作按钮
 * 
 * 用于控制列表或其它地方上的按钮的操作权限
 * </pre>
 * @author jackson
 *
 */
public class BaseButtonResolver implements Comparable<BaseButtonResolver>, IExpressionParameter{
	/**
	 * <pre>
	 * 用来控制访问的权限的，访问权限可以定义在菜单文件里，
	 * 在制定角色操作权限的时候可以指定某个角色有某些操作权限；
	 * 只有当前操作的用户具有相应的操作权限，才能对该功能进行操作；
	 * 
	 * 如：访问权限设置为1(key=1)，相应的在菜单定义文件里需要定义
	 * 某个菜单下的操作权限，例如把1定义为禁止操作的操作权限，那么在
	 * 定义角色的时候，就可以选择某个操作菜单，该操作菜单下就有"禁止"
	 * 的操作权限，如果选中，则具有该角色的用户可以使用"禁止"功能，
	 * 否则该角色的用户将无法操作"禁止"功能。
	 * </pre>
	 */
	protected int key = OperandSupport.OPERAND_NOT;
	/**
	 * 按钮显示的名称
	 */
	protected String name;
	/**
	 * 在控制器里调用，对该按钮设置自定义的处理事件
	 */
	protected String url;
	
	/**
	 * 该按钮事件的类型，如：弹出对话框、ajax提交等
	 */
	protected ButtonEventType eventType;
	/**
	 * 表示该按钮是否需要刷新列表
	 */
	protected ButtonRefreshType refreshType;
	
	protected String functionName;

	/**
	 * 按钮上显示的小图标
	 */
	protected String iconCls;
	protected String title;
	
	/**
	 * 通过访问路径进行参数的传递
	 */
	protected List<QueryParameter> parameters;
	private String click;
	
	public List<QueryParameter> getParameters(){
		return parameters;
	}
	
	@Override
	public void addQueryParameter(QueryParameter parameter) {
		if(null == parameters){
			//一般不会使用路径来传递参数，如果有，也则是1、2个的情况比较多，所以为了节省内存空间，默认情况下认为最多的情况不超过2个参数
			parameters = new ArrayList<QueryParameter>(2);
		}
		parameters.add(parameter);
	}
	
	@Override
	public void addQueryParameter(String name, String value) {
		addQueryParameter(new QueryParameter(name, value));
	}
	
	@Override
	public void addQueryParameter(String name, String value, QueryParameterType type) {
		addQueryParameter(new QueryParameter(name, value, type));
	}
	
	public BaseButtonResolver addParameter(String name, String value){
		if(null == parameters){
			//一般不会使用路径来传递参数，如果有，也则是1、2个的情况比较多，所以为了节省内存空间，默认情况下认为最多的情况不超过2个参数
			parameters = new ArrayList<QueryParameter>(2);
		}
		parameters.add(new QueryParameter(name, value));
		return this;
	}
	
	public BaseButtonResolver addParameter(List<QueryParameter> parameters){
		if(null != parameters){
			if(null == this.parameters){
				this.parameters = parameters;
			}else{
				this.parameters.addAll(parameters);
			}
		}
		return this;
	}
	
	public void event(StringBuilder js, String beforeOperate, String afterOperate){
		eventType.parse(js, beforeOperate, name, refreshType, afterOperate);
	}
	
	protected StringBuilder parseUrl(String url){
		StringBuilder sburl = new StringBuilder(url);
		if(null != parameters && !parameters.isEmpty()){
			char c = url.indexOf('?') == -1 ? '?' : '&';
			for(QueryParameter qp : parameters){
				qp.request(sburl.append(c));
				c = '&';
			}
		}
		return sburl;
	}


	public boolean clickable() {
		
		return eventType == ButtonEventType.FORM 
				|| eventType == ButtonEventType.GET
				|| eventType == ButtonEventType.DIALOG
				|| eventType == ButtonEventType.POST;
	}
	private boolean bupabutton = true;
	public void setBupabutton(boolean bupabutton) {
		this.bupabutton = bupabutton;
	}
	public void button(StringBuilder html, String buttonId){
		if(StringHelper.isEmpty(title)){
			title = name;
		}
		html.append("<a href='").append(parseUrl(url))
			.append("' id='").append(buttonId)
			.append("' title='").append(title).append("'");
		if(bupabutton){
			html.append(" class='bupabutton' data-settings=\"flat:true");
			if(StringHelper.isNotEmpty(iconCls)){
				html.append(",iconClassname:'").append(iconCls).append('\'');
			}
			html.append('"');
		}else if(StringHelper.isNotEmpty(iconCls)){
			html.append(" style='padding-left:20px;' class='").append(iconCls).append("'");
		}
		if(eventType == ButtonEventType.JUMP){
			html.append(" target='_blank'");
		}else{
			if(StringHelper.isNotEmpty(click)){
				html.append(" onclick='").append(click).append("'");
			}
		}
		html.append('>').append(name).append("</a>");
	}
	
	public void setClick(String click) {
		this.click = click;
	}
	
	public String getIconCls() {
		return iconCls;
	}
	
	public void setIconCls(String iconCls) {
		this.iconCls = iconCls;
	}
	
	public void setEventType(ButtonEventType eventType) {
		this.eventType = eventType;
	}
	
	public void setRefreshType(ButtonRefreshType refreshType) {
		this.refreshType = refreshType;
	}

	/**
	 * <pre>
	 * 框架默认提供操作符：{@link cn.bonoon.kernel.support.OperandSupport}
	 * </pre>
	 * 具体的说明可以查看：{@link #key}
	 * @param key
	 */
	public void setKey(int key) {
		this.key = key;
	}

	public void setName(String name) {
		this.name = name;
	}

	public void setUrl(String url) {
		this.url = url;
	}
	
	public void setFunctionName(String functionName) {
		this.functionName = functionName;
	}
	
	/**
	 * <pre>
	 * 指定按钮的操作函数的时候，有两种可能：
	 * 1.如果没有函数的方法体，则表示该按钮调用该函数
	 * 2.如果子类有方法体，则表示需要根据函数名来生成一个函数，这个函数可能会被其它调用
	 * </pre>
	 * @return
	 */
	public String getFunctionName() {
		return functionName;
	}
	
	public ButtonRefreshType getRefreshType() {
		return refreshType;
	}
	
	public String getUrl() {
		return url;
	}
	
	public String getName() {
		return name;
	}
	
	public int getKey() {
		return key;
	}
	
	public ButtonEventType getEventType() {
		return eventType;
	}

	public String getTitle() {
		return title;
	}

	public BaseButtonResolver title(String title) {
		this.title = title;
		return this;
	}
	
	private int ordinal;

	public void ordinal(int ordinal) {
		this.ordinal = ordinal;
	}
	
	@Override
	public int compareTo(BaseButtonResolver o) {
		return ordinal - o.ordinal;
	}
}
